#ifndef TREE_H
#define TREE_H

#define STRLEN 20
#include <string>

using namespace std;

typedef struct Node{
    Node   *lft;
    Node   *rht;
    Node   *anc;
    int   index;
    bool   isLeaf;
    char *   name;
    bool   flag;
    double   v;
    int childrenLeft;
} Node;

Node *  createNode();
Node   *getLft(Node * thisNode);
Node   *getRht(Node * thisNode);
Node   *getAnc(Node * thisNode);
int   getIndex(Node * thisNode);
bool   getIsLeaf(Node * thisNode);
string   getName(Node * thisNode);
bool   getFlag(Node * thisNode);
double   getV(Node * thisNode);
void   setLft(Node * thisNode, Node *p);
void   setRht(Node * thisNode, Node *p);
void   setAnc(Node * thisNode, Node *p);
void   setIndex(Node * thisNode, int x);
void   setIsLeaf(Node * thisNode, bool x);
void   setName(Node * thisNode, const char * s);
void   setFlag(Node * thisNode, bool x);
void   setV(Node * thisNode, double x);





class Alignment;
class MbRandom;

    
typedef struct {
    Alignment   *alignmentPtr;
    MbRandom   *ranPtr;
    Node   *nodes;
    Node   *root;
    Node   **downPassSequence;
    Node   **nextQueue;
    int queueStart;
    int queueEnd;
    int   numTaxa;
    int   numNodes;
    bool   isRooted;
} Tree;

void completeNode(Tree * thisTree, Node *p);
void enqueue(Tree * thisTree, Node *p);
Node *dequeue(Tree * thisTree);

Tree * createTree(Alignment *al, MbRandom *rp, string treeStr);
void deleteTree(Tree * thisTree);
int   getNumTaxa(Tree * thisTree);
int   getNumNodes(Tree * thisTree);
void   getDownPassSequence(Tree * thisTree);
Node   *getRoot(Tree * thisTree);
Node   *getDownPassNode(Tree * thisTree, int i);
void   print(Tree * thisTree);

//void   buildTreeFromNewickString(string treeStr);
//void   buildRandomTree(void);
//int   dex(Node *p);
//void   passDn(Node *p, int *x);
//void   showNodes(Node *p, int indent);


#endif
